#include "sleep.h"
#include "globalDef.h"
#include "gd32e10x_rcu.h"
#include "tim_hw.h"
#include "debug_prt.h"
#include "CarMonitor.h"
#include "led.h"


#if _EnSleep_def


/*
0:	退出休眠,不是立即退出休眠，是等5秒后才进入休眠
1：	进入sleep
*/
uint8_t	sleepStatue = 0;

static uint32_t OldSec = 0;	//用于延时5秒
static uint32_t NewSec = 0;




/*
处理休眠的进程
如果发现 sleepStatue = 1则进入休眠，同时启动定时器0.4秒
定时器在0.4秒后触发中断，退出休眠
如果发现sleepStatue = 0，则关闭定时器中断，跳出该函数

某小板实测14V低功耗时降低了0.3mA，对应3.3V应该能降低1mA左右。
*/
void sleep_process(void)
{

	
	switch (sleepStatue)
	{
		case 0x00:
			//关闭定时器，退出
			sleepStatue = 0x10;	//省得每次都要给寄存器赋值，减少读写寄存器次数
			
			StopTimerForWakeup();
		
			#if _EnSleepDebug_def
			printf("exit sleep\r\n");
			#endif
			setLEDStatues(2);
			
			break;
		
		case 0x01:	//休眠前延时5秒
			sleepStatue = 0x02;
			OldSec = get1sCounter();
			break;

		case 0x02:
			NewSec = get1sCounter();
			if ((NewSec - OldSec) >= 5)
			{
				sleepStatue = 0x03;		//启动休眠
			}
			break;
		
		case 0x03:
			
			/* PMU clock enable */
			rcu_periph_clock_enable(RCU_PMU);
			
			if (getLowPowerSta() == 0x00)
			{
				//启动定时器，非低压时0.04秒唤醒1次
				StartTimerForWakeup();
				#if _EnSleepDebug_def
				printf("go sleep 0.04s\r\n");
				#endif
			}
			else
			{
				//调用5秒定时器，为了省电。低压时5秒唤醒1次
				StartLongTimerForWakeup();
				printf("go sleep 5s\r\n");
				//carVoltageMonitor();
			}
			
			
			//进入休眠
			pmu_to_sleepmode(WFI_CMD);
			
			//等待任意中断唤醒后执行后续代码
			//..
			setLEDStatues(3);			
		
			break;
		
		case 0x10:
			//如果有中断，请在中断中增加wakeup();
			//主程序没事时一直休眠
			sleep();	
			break;
		
	}
	
	//调试休眠部分代码，正式工程请注释掉
	#if 0
	{
		static uint8_t runOnce = 0;

		
		if (runOnce == 0x00)
		{
			runOnce = 0x01;
			sleep();		//延时5秒后休眠
			//sleepImmediately();	//立即休眠
			debug_prt((uint8_t*)"e",1);
		}
		//调试测试休眠, 通过PC看是否0.4秒输出1次
		if ((runOnce == 0x01) && (sleepStatue == 0x03))
		{
			debug_prt((uint8_t*)"w",1);
		}

	}
	#endif
	
}



#endif	//_EnSleep_def


